<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><link rel="stylesheet" type="text/css" href="style.css" /><script type="text/javascript" src="highlight.js"></script></head><body><pre><span class="hs-pragma">{-# LANGUAGE Trustworthy #-}</span><span>
</span><span id="line-2"></span><span class="hs-pragma">{-# LANGUAGE NoImplicitPrelude #-}</span><span>
</span><span id="line-3"></span><span>
</span><span id="line-4"></span><span class="hs-comment">-----------------------------------------------------------------------------</span><span>
</span><span id="line-5"></span><span class="hs-comment">-- |</span><span>
</span><span id="line-6"></span><span class="hs-comment">-- Module      :  Data.Function</span><span>
</span><span id="line-7"></span><span class="hs-comment">-- Copyright   :  Nils Anders Danielsson 2006</span><span>
</span><span id="line-8"></span><span class="hs-comment">--             ,  Alexander Berntsen     2014</span><span>
</span><span id="line-9"></span><span class="hs-comment">-- License     :  BSD-style (see the LICENSE file in the distribution)</span><span>
</span><span id="line-10"></span><span class="hs-comment">--</span><span>
</span><span id="line-11"></span><span class="hs-comment">-- Maintainer  :  libraries@haskell.org</span><span>
</span><span id="line-12"></span><span class="hs-comment">-- Stability   :  experimental</span><span>
</span><span id="line-13"></span><span class="hs-comment">-- Portability :  portable</span><span>
</span><span id="line-14"></span><span class="hs-comment">--</span><span>
</span><span id="line-15"></span><span class="hs-comment">-- Simple combinators working solely on and with functions.</span><span>
</span><span id="line-16"></span><span class="hs-comment">--</span><span>
</span><span id="line-17"></span><span class="hs-comment">-----------------------------------------------------------------------------</span><span>
</span><span id="line-18"></span><span>
</span><span id="line-19"></span><span class="hs-keyword">module</span><span> </span><span class="hs-identifier">Data.Function</span><span>
</span><span id="line-20"></span><span>  </span><span class="hs-special">(</span><span> </span><span class="annot"><span class="hs-comment">-- * &quot;Prelude&quot; re-exports</span></span><span>
</span><span id="line-21"></span><span>    </span><span class="annot"><a href="GHC.Base.html#id"><span class="hs-identifier">id</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#const"><span class="hs-identifier">const</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#."><span class="hs-operator">(.)</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#flip"><span class="hs-identifier">flip</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#%24"><span class="hs-operator">($)</span></a></span><span>
</span><span id="line-22"></span><span>    </span><span class="annot"><span class="hs-comment">-- * Other combinators</span></span><span>
</span><span id="line-23"></span><span>  </span><span class="hs-special">,</span><span> </span><span class="annot"><a href="Data.Function.html#%26"><span class="hs-operator">(&amp;)</span></a></span><span>
</span><span id="line-24"></span><span>  </span><span class="hs-special">,</span><span> </span><span class="annot"><a href="Data.Function.html#fix"><span class="hs-identifier">fix</span></a></span><span>
</span><span id="line-25"></span><span>  </span><span class="hs-special">,</span><span> </span><span class="annot"><a href="Data.Function.html#on"><span class="hs-identifier">on</span></a></span><span>
</span><span id="line-26"></span><span>  </span><span class="hs-special">)</span><span> </span><span class="hs-keyword">where</span><span>
</span><span id="line-27"></span><span>
</span><span id="line-28"></span><span class="hs-keyword">import</span><span> </span><span class="annot"><a href="GHC.Base.html"><span class="hs-identifier">GHC.Base</span></a></span><span> </span><span class="hs-special">(</span><span> </span><span class="annot"><a href="GHC.Base.html#%24"><span class="hs-operator">($)</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#."><span class="hs-operator">(.)</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#id"><span class="hs-identifier">id</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#const"><span class="hs-identifier">const</span></a></span><span class="hs-special">,</span><span> </span><span class="annot"><a href="GHC.Base.html#flip"><span class="hs-identifier">flip</span></a></span><span> </span><span class="hs-special">)</span><span>
</span><span id="line-29"></span><span>
</span><span id="line-30"></span><span class="hs-keyword">infixl</span><span> </span><span class="hs-number">0</span><span> </span><span class="annot"><a href="Data.Function.html#on"><span class="hs-operator hs-type">`on`</span></a></span><span>
</span><span id="line-31"></span><span class="hs-keyword">infixl</span><span> </span><span class="hs-number">1</span><span> </span><span class="annot"><a href="Data.Function.html#%26"><span class="hs-operator hs-type">&amp;</span></a></span><span>
</span><span id="line-32"></span><span>
</span><span id="line-33"></span><span class="hs-comment">-- | @'fix' f@ is the least fixed point of the function @f@,</span><span>
</span><span id="line-34"></span><span class="hs-comment">-- i.e. the least defined @x@ such that @f x = x@.</span><span>
</span><span id="line-35"></span><span class="hs-comment">--</span><span>
</span><span id="line-36"></span><span class="hs-comment">-- For example, we can write the factorial function using direct recursion as</span><span>
</span><span id="line-37"></span><span class="hs-comment">--</span><span>
</span><span id="line-38"></span><span class="hs-comment">-- &gt;&gt;&gt; let fac n = if n &lt;= 1 then 1 else n * fac (n-1) in fac 5</span><span>
</span><span id="line-39"></span><span class="hs-comment">-- 120</span><span>
</span><span id="line-40"></span><span class="hs-comment">--</span><span>
</span><span id="line-41"></span><span class="hs-comment">-- This uses the fact that Haskell&#8217;s @let@ introduces recursive bindings. We can</span><span>
</span><span id="line-42"></span><span class="hs-comment">-- rewrite this definition using 'fix',</span><span>
</span><span id="line-43"></span><span class="hs-comment">--</span><span>
</span><span id="line-44"></span><span class="hs-comment">-- &gt;&gt;&gt; fix (\rec n -&gt; if n &lt;= 1 then 1 else n * rec (n-1)) 5</span><span>
</span><span id="line-45"></span><span class="hs-comment">-- 120</span><span>
</span><span id="line-46"></span><span class="hs-comment">--</span><span>
</span><span id="line-47"></span><span class="hs-comment">-- Instead of making a recursive call, we introduce a dummy parameter @rec@;</span><span>
</span><span id="line-48"></span><span class="hs-comment">-- when used within 'fix', this parameter then refers to 'fix'&#8217;s argument, hence</span><span>
</span><span id="line-49"></span><span class="hs-comment">-- the recursion is reintroduced.</span><span>
</span><span id="line-50"></span><span id="local-6989586621679558341"><span class="annot"><a href="Data.Function.html#fix"><span class="hs-identifier hs-type">fix</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="#local-6989586621679558341"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558341"><span class="hs-identifier hs-type">a</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558341"><span class="hs-identifier hs-type">a</span></a></span></span><span>
</span><span id="line-51"></span><span id="fix"><span class="annot"><span class="annottext">fix :: forall a. (a -&gt; a) -&gt; a
</span><a href="Data.Function.html#fix"><span class="hs-identifier hs-var hs-var">fix</span></a></span></span><span> </span><span id="local-6989586621679558322"><span class="annot"><span class="annottext">a -&gt; a
</span><a href="#local-6989586621679558322"><span class="hs-identifier hs-var">f</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-keyword">let</span><span> </span><span id="local-6989586621679558321"><span class="annot"><span class="annottext">x :: a
</span><a href="#local-6989586621679558321"><span class="hs-identifier hs-var hs-var">x</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">a -&gt; a
</span><a href="#local-6989586621679558322"><span class="hs-identifier hs-var">f</span></a></span><span> </span><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558321"><span class="hs-identifier hs-var">x</span></a></span><span> </span><span class="hs-keyword">in</span><span> </span><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558321"><span class="hs-identifier hs-var">x</span></a></span><span>
</span><span id="line-52"></span><span>
</span><span id="line-53"></span><span class="hs-comment">-- | @'on' b u x y@ runs the binary function @b@ /on/ the results of applying</span><span>
</span><span id="line-54"></span><span class="hs-comment">-- unary function @u@ to two arguments @x@ and @y@. From the opposite</span><span>
</span><span id="line-55"></span><span class="hs-comment">-- perspective, it transforms two inputs and combines the outputs.</span><span>
</span><span id="line-56"></span><span class="hs-comment">--</span><span>
</span><span id="line-57"></span><span class="hs-comment">-- @((+) \``on`\` f) x y = f x + f y@</span><span>
</span><span id="line-58"></span><span class="hs-comment">--</span><span>
</span><span id="line-59"></span><span class="hs-comment">-- Typical usage: @'Data.List.sortBy' ('Prelude.compare' \`on\` 'Prelude.fst')@.</span><span>
</span><span id="line-60"></span><span class="hs-comment">--</span><span>
</span><span id="line-61"></span><span class="hs-comment">-- Algebraic properties:</span><span>
</span><span id="line-62"></span><span class="hs-comment">--</span><span>
</span><span id="line-63"></span><span class="hs-comment">-- * @(*) \`on\` 'id' = (*) -- (if (*) &amp;#x2209; {&amp;#x22a5;, 'const' &amp;#x22a5;})@</span><span>
</span><span id="line-64"></span><span class="hs-comment">--</span><span>
</span><span id="line-65"></span><span class="hs-comment">-- * @((*) \`on\` f) \`on\` g = (*) \`on\` (f . g)@</span><span>
</span><span id="line-66"></span><span class="hs-comment">--</span><span>
</span><span id="line-67"></span><span class="hs-comment">-- * @'flip' on f . 'flip' on g = 'flip' on (g . f)@</span><span>
</span><span id="line-68"></span><span id="local-6989586621679558337"><span id="local-6989586621679558338"><span id="local-6989586621679558339"><span class="annot"><a href="Data.Function.html#on"><span class="hs-identifier hs-type">on</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="#local-6989586621679558339"><span class="hs-identifier hs-type">b</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558339"><span class="hs-identifier hs-type">b</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558338"><span class="hs-identifier hs-type">c</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="#local-6989586621679558337"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558339"><span class="hs-identifier hs-type">b</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558337"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558337"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558338"><span class="hs-identifier hs-type">c</span></a></span></span></span></span><span>
</span><span id="line-69"></span><span id="local-6989586621679558320"><span class="annot"><span class="annottext">b -&gt; b -&gt; c
</span><a href="#local-6989586621679558320"><span class="hs-operator hs-var">(.*.)</span></a></span></span><span> </span><span id="on"><span class="annot"><span class="annottext">on :: forall b c a. (b -&gt; b -&gt; c) -&gt; (a -&gt; b) -&gt; a -&gt; a -&gt; c
</span><a href="Data.Function.html#on"><span class="hs-operator hs-var hs-var">`on`</span></a></span></span><span> </span><span id="local-6989586621679558319"><span class="annot"><span class="annottext">a -&gt; b
</span><a href="#local-6989586621679558319"><span class="hs-identifier hs-var">f</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="hs-glyph">\</span><span id="local-6989586621679558318"><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558318"><span class="hs-identifier hs-var">x</span></a></span></span><span> </span><span id="local-6989586621679558317"><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558317"><span class="hs-identifier hs-var">y</span></a></span></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><span class="annottext">a -&gt; b
</span><a href="#local-6989586621679558319"><span class="hs-identifier hs-var">f</span></a></span><span> </span><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558318"><span class="hs-identifier hs-var">x</span></a></span><span> </span><span class="annot"><span class="annottext">b -&gt; b -&gt; c
</span><a href="#local-6989586621679558320"><span class="hs-operator hs-var">.*.</span></a></span><span> </span><span class="annot"><span class="annottext">a -&gt; b
</span><a href="#local-6989586621679558319"><span class="hs-identifier hs-var">f</span></a></span><span> </span><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558317"><span class="hs-identifier hs-var">y</span></a></span><span>
</span><span id="line-70"></span><span class="hs-comment">-- Proofs (so that I don't have to edit the test-suite):</span><span>
</span><span id="line-71"></span><span>
</span><span id="line-72"></span><span class="hs-comment">--   (*) `on` id</span><span>
</span><span id="line-73"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-74"></span><span class="hs-comment">--   \x y -&gt; id x * id y</span><span>
</span><span id="line-75"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-76"></span><span class="hs-comment">--   \x y -&gt; x * y</span><span>
</span><span id="line-77"></span><span class="hs-comment">-- = { If (*) /= _|_ or const _|_. }</span><span>
</span><span id="line-78"></span><span class="hs-comment">--   (*)</span><span>
</span><span id="line-79"></span><span>
</span><span id="line-80"></span><span class="hs-comment">--   (*) `on` f `on` g</span><span>
</span><span id="line-81"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-82"></span><span class="hs-comment">--   ((*) `on` f) `on` g</span><span>
</span><span id="line-83"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-84"></span><span class="hs-comment">--   \x y -&gt; ((*) `on` f) (g x) (g y)</span><span>
</span><span id="line-85"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-86"></span><span class="hs-comment">--   \x y -&gt; (\x y -&gt; f x * f y) (g x) (g y)</span><span>
</span><span id="line-87"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-88"></span><span class="hs-comment">--   \x y -&gt; f (g x) * f (g y)</span><span>
</span><span id="line-89"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-90"></span><span class="hs-comment">--   \x y -&gt; (f . g) x * (f . g) y</span><span>
</span><span id="line-91"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-92"></span><span class="hs-comment">--   (*) `on` (f . g)</span><span>
</span><span id="line-93"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-94"></span><span class="hs-comment">--   (*) `on` f . g</span><span>
</span><span id="line-95"></span><span>
</span><span id="line-96"></span><span class="hs-comment">--   flip on f . flip on g</span><span>
</span><span id="line-97"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-98"></span><span class="hs-comment">--   (\h (*) -&gt; (*) `on` h) f . (\h (*) -&gt; (*) `on` h) g</span><span>
</span><span id="line-99"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-100"></span><span class="hs-comment">--   (\(*) -&gt; (*) `on` f) . (\(*) -&gt; (*) `on` g)</span><span>
</span><span id="line-101"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-102"></span><span class="hs-comment">--   \(*) -&gt; (*) `on` g `on` f</span><span>
</span><span id="line-103"></span><span class="hs-comment">-- = { See above. }</span><span>
</span><span id="line-104"></span><span class="hs-comment">--   \(*) -&gt; (*) `on` g . f</span><span>
</span><span id="line-105"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-106"></span><span class="hs-comment">--   (\h (*) -&gt; (*) `on` h) (g . f)</span><span>
</span><span id="line-107"></span><span class="hs-comment">-- =</span><span>
</span><span id="line-108"></span><span class="hs-comment">--   flip on (g . f)</span><span>
</span><span id="line-109"></span><span>
</span><span id="line-110"></span><span>
</span><span id="line-111"></span><span class="hs-comment">-- | '&amp;' is a reverse application operator.  This provides notational</span><span>
</span><span id="line-112"></span><span class="hs-comment">-- convenience.  Its precedence is one higher than that of the forward</span><span>
</span><span id="line-113"></span><span class="hs-comment">-- application operator '$', which allows '&amp;' to be nested in '$'.</span><span>
</span><span id="line-114"></span><span class="hs-comment">--</span><span>
</span><span id="line-115"></span><span class="hs-comment">-- &gt;&gt;&gt; 5 &amp; (+1) &amp; show</span><span>
</span><span id="line-116"></span><span class="hs-comment">-- &quot;6&quot;</span><span>
</span><span id="line-117"></span><span class="hs-comment">--</span><span>
</span><span id="line-118"></span><span class="hs-comment">-- @since 4.8.0.0</span><span>
</span><span id="line-119"></span><span id="local-6989586621679558332"><span id="local-6989586621679558333"><span class="annot"><a href="Data.Function.html#%26"><span class="hs-operator hs-type">(&amp;)</span></a></span><span> </span><span class="hs-glyph">::</span><span> </span><span class="annot"><a href="#local-6989586621679558333"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="hs-special">(</span><span class="annot"><a href="#local-6989586621679558333"><span class="hs-identifier hs-type">a</span></a></span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558332"><span class="hs-identifier hs-type">b</span></a></span><span class="hs-special">)</span><span> </span><span class="hs-glyph">-&gt;</span><span> </span><span class="annot"><a href="#local-6989586621679558332"><span class="hs-identifier hs-type">b</span></a></span></span></span><span>
</span><span id="line-120"></span><span id="local-6989586621679558316"><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558316"><span class="hs-identifier hs-var">x</span></a></span></span><span> </span><span id="%26"><span class="annot"><span class="annottext">&amp; :: forall a b. a -&gt; (a -&gt; b) -&gt; b
</span><a href="Data.Function.html#%26"><span class="hs-operator hs-var hs-var">&amp;</span></a></span></span><span> </span><span id="local-6989586621679558315"><span class="annot"><span class="annottext">a -&gt; b
</span><a href="#local-6989586621679558315"><span class="hs-identifier hs-var">f</span></a></span></span><span> </span><span class="hs-glyph">=</span><span> </span><span class="annot"><span class="annottext">a -&gt; b
</span><a href="#local-6989586621679558315"><span class="hs-identifier hs-var">f</span></a></span><span> </span><span class="annot"><span class="annottext">a
</span><a href="#local-6989586621679558316"><span class="hs-identifier hs-var">x</span></a></span><span>
</span><span id="line-121"></span><span>
</span><span id="line-122"></span><span class="hs-comment">-- $setup</span><span>
</span><span id="line-123"></span><span class="hs-comment">-- &gt;&gt;&gt; import Prelude</span><span>
</span><span id="line-124"></span></pre></body></html>